import os, sys
sys.path.append("..")
sys.path.append(os.getcwd())
import data_process.radiation_process as rp

from math import sqrt
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
from keras.optimizers import Adam
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM

# 读取CSV文件
data = pd.read_csv('data_resource\\radiation_data2.csv')
# 转换时间列为日期时间格式
data['timestamp'] = pd.to_datetime(data['timestamp'])

# 找到最早日期作为基准日期
baseline_date = data['timestamp'].min()

# 创建DataFrame
df = pd.DataFrame({'Time': data['timestamp'], 'Concentration': data['concentration']})
# 将时间戳转换为相对于基准日期的天数
df['Days_From_Baseline'] = (df['Time'] - baseline_date).dt.days

values = df['Concentration']

# 进行数据处理
reframed,scaler = rp.radiation_data_process(values)

# 预测数据准备
values = reframed.values
print(values)

# 拿3/4的时间长度训练 数据集中每天记录了四次数据
n_train_hours = 365 * 3
# 划分训练数据和测试数据
train = values[:n_train_hours, :]
test = values[n_train_hours:, :]
# 拆分输入输出 split into input and outputs
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
#reshape输入为LSTM的输入格式 reshape input to be 3D [samples, timesteps, features]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print ('train_x.shape, train_y.shape, test_x.shape, test_y.shape')
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)

# 设置超参数
num_units = 64  # LSTM 层中的单元数
num_layers = 2  # LSTM 层数
learning_rate = 5e-5  # 学习率

# 创建 LSTM 模型
model = Sequential()
model.add(LSTM(units=num_units, input_shape=(train_X.shape[1], train_X.shape[2]), return_sequences=True))
for _ in range(num_layers - 1):
    model.add(LSTM(units=num_units, return_sequences=True))
model.add(Dense(units=1))

# 编译模型，指定优化器和学习率
optimizer = Adam(lr=learning_rate)
model.compile(loss='mae', optimizer=optimizer)

# 模型训练 fit network
history = model.fit(train_X, train_y, epochs=5, batch_size=72, validation_data=(test_X, test_y), verbose=2,
                    shuffle=False)

#输出 plot history
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')
plt.legend()
plt.show()

# 模型预测及数据准备
yhat = model.predict(test_X)
test_X_reshaped = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))

# 进行预测 make a prediction
yhat = model.predict(test_X_reshaped)
test_X_reshaped = test_X_reshaped.reshape((test_X_reshaped.shape[0], test_X_reshaped.shape[2]))

# 预测数据逆缩放 invert scaling for forecast
inv_yhat = yhat[:, 0]
inv_yhat = inv_yhat.reshape(-1, 1)
inv_yhat = scaler.inverse_transform(inv_yhat)
inv_yhat = inv_yhat[:, 0]

# 真实数据逆缩放 invert scaling for actual
test_y = test_y.reshape(-1, 1)
inv_y = scaler.inverse_transform(test_y)
inv_y = inv_y[:, 0]

# 画出真实数据和预测数据
plt.plot(inv_yhat, label='prediction')
plt.plot(inv_y, label='true')
plt.legend()
plt.xlim(240, 400)
plt.show()



# calculate RMSE
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
print('Test RMSE: %.3f' % rmse)